package edu.arizona.sista.learn.activity.experiment;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import edu.arizona.sista.learn.activity.model.ActivityInstance;
import edu.arizona.sista.learn.activity.model.Predicate;
import edu.arizona.sista.learn.activity.model.PredicateInterval;
import edu.arizona.sista.learn.activity.util.KnownPredicates;
import edu.arizona.sista.learn.activity.util.Utils;

public class RecognitionExperiment {
	
	public static void main(String[] args) {
		
		recognition(KnownPredicates.approach, "data/input/fluents/approach.lisp");
		recognition(KnownPredicates.chase, "data/input/fluents/chase.lisp");	
		recognition(KnownPredicates.flee, "data/input/fluents/chase.lisp");
		recognition(KnownPredicates.flee, "data/input/fluents/flee.lisp");
		recognition(KnownPredicates.get, "data/input/fluents/give.lisp");

		String file = "data/output/test-fluents.lisp";
		recognition(file);

	}

	/**
	 * Search for a specific activity pattern in the instances given by the file.
	 * @param filepath Path to file containing the activity instances.
	 * @param instance Activity instances to search in.
	 * @return A list of results, where each result is a list of predicate-intervals
	 * during which the activity was detected.
	 */
	public static List<List<PredicateInterval>> recognition(Predicate pattern, String filepath){
		System.out.println("\n----\nActivity pattern: " + pattern.getName().toUpperCase() + "\n");
		List<List<PredicateInterval>> results = new ArrayList<List<PredicateInterval>>();
		for (ActivityInstance inst: ActivityInstance.load(new File(filepath))){
			System.out.println("Instance " + inst.id());
			results.add(recognition(pattern, inst));
		}
		return results;
	}
	
	/**
	 * Search for all possible activity patterns in the instances given by the file.
	 * @param filepath Path to file containing the activity instances.
	 * @return One hash map of activity-results for each instance, where the key is
	 * the name of the activity and the value is a list of predicate-intervals
	 * during which the activity was detected.
	 */
	public static List<Map<String, List<PredicateInterval>>> recognition(String filepath) {
		return recognition(ActivityInstance.load(new File(filepath)));
	}
	
	/**
	 * Search for all possible activity patterns in the given instances.
	 * @param instance Activity instance to search in.
	 * @return One hash map of activity-results for each instance, where the key is
	 * the name of the activity and the value is a list of predicate-intervals
	 * during which the activity was detected.
	 */
	public static List<Map<String, List<PredicateInterval>>> recognition(List<ActivityInstance> instances) {
		List<Map<String, List<PredicateInterval>>> results = new ArrayList<Map<String,List<PredicateInterval>>>();
		for (ActivityInstance inst: instances){
			System.out.println("\n----\nInstance " + inst.id() + "\n");
			results.add(recognition(inst));
		}
		return results; 
	}

	/**
	 * Search for all possible activity patterns in the given instance.
	 * Fluents are automatically "glued" together to improve continuity and
	 * prevent fragmented fluents.
	 * @param instance Activity instance to search in.
	 * @return A hash map of activity-results, where the key is the name of the
	 * activity and the value is a list of predicate-intervals during which
	 * the activity was detected.
	 */
	public static Map<String, List<PredicateInterval>> recognition(ActivityInstance instance) {
		return recognition(instance, true);
	}
	
	/** Search for all possible activity patterns in the given instance.
	 * @param instance Activity instance to search in.
	 * @param glue Flag to whether or not fragmented fluents should be
	 * "glued" together.
	 * @return A hash map of activity-results, where the key is the name of the
	 * activity and the value is a list of predicate-intervals during which
	 * the activity was detected.
	 */
	public static Map<String, List<PredicateInterval>> recognition(ActivityInstance instance, boolean glue) {
		Map<String, List<PredicateInterval>> results = new HashMap<String, List<PredicateInterval>>();
		for (Predicate pattern : KnownPredicates.evaluationVerbs) {
			System.out.println("Activity pattern: " + pattern.getName().toUpperCase());
			results.put(pattern.getName(), recognition(pattern, instance));
		}
		
		if (glue)
			return Utils.glue(results, 0.5, 1);
		
		return results;
	}
	
	/**
	 * Search for a specific activity pattern in the given instance.
	 * @param pattern Activity pattern to search for.
	 * @param instance Activity instance to search in.
	 * @return List of predicate-intervals during which the activity was detected.
	 */
	public static List<PredicateInterval> recognition(Predicate pattern, ActivityInstance instance){
		List<PredicateInterval> result = pattern.findIn(instance);
		if (!result.isEmpty()) {
			for (PredicateInterval i : result) {
				System.out.println(" - " + i.start + " " + i.end + " " + i.getName());
			}
		} else {
			System.out.println("Did not find the behavior.");
		}
		System.out.println("");
		return result;
	}
	
}
